package 线程安全;

public class 单例模式_懒汉式_双重校验锁 {
    private static volatile 单例模式_懒汉式_双重校验锁 instance = null;

    //这样写，满足线程安全；为什么说，这样写效率低？
    //1.在instance=null的时候，如果有多个线程调用getInstance，需要保证线程安全（一个线程写，其他线程读）
    //2.在instance已经赋值给一个创建好的对象以后，再有多个线程调用getInstance（多个线程读）
    //考虑优化：第1个情况，加锁，第2个情况，使用volatile就可以了
    public static 单例模式_懒汉式_双重校验锁 getInstance(){
        //第1个情况，instance=null, 多个线程会进入
        if(instance == null) {//保证第2个情况，已经实例化对象，不需要再次竞争锁
            //第1个情况，多个线程进入到这行代码，一个线程竞争成功，执行同步代码，其他线程竞争失败阻塞
            synchronized (单例模式_懒汉式_双重校验锁.class){
                //这里的if还需要吗？如果没有这里的if，第1个情况的多个线程就创建了多个不同的实例对象
                //就不满足单例的条件
                if(instance == null) {
                    instance = new 单例模式_懒汉式_双重校验锁();
                }
            }
        }
        return instance;
    }
}
